From 3e1f6721709c60dd17dd41c0aeeb5b80abcd8b21 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 15 Sep 2017 18:31:18 +0200 Subject: [PATCH] gdk: Drop generation of synthesized crossing events on grabs GDK just needs to care about toplevels nowadays, which means these events are already delivered from the windowing. We don't need to generate intra-window crossing events ourselves. --- gdk/gdkdisplay.c | 117 +--------------- gdk/gdkwindow.c | 350 ----------------------------------------------- 2 files changed, 1 insertion(+), 466 deletions(-) diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index bdc9dabde5..a4a75bc2fb 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -806,97 +806,6 @@ _gdk_display_end_touch_grab (GdkDisplay *display, return FALSE; } -/* _gdk_synthesize_crossing_events only works inside one toplevel. - This function splits things into two calls if needed, converting the - coordinates to the right toplevel */ -static void -synthesize_crossing_events (GdkDisplay *display, - GdkDevice *device, - GdkDevice *source_device, - GdkWindow *src_window, - GdkWindow *dest_window, - GdkCrossingMode crossing_mode, - guint32 time, - gulong serial) -{ - GdkWindow *src_toplevel, *dest_toplevel; - GdkModifierType state; - double x, y; - - if (src_window) - src_toplevel = gdk_window_get_toplevel (src_window); - else - src_toplevel = NULL; - if (dest_window) - dest_toplevel = gdk_window_get_toplevel (dest_window); - else - dest_toplevel = NULL; - - if (src_toplevel == NULL && dest_toplevel == NULL) - return; - - if (src_toplevel == NULL || - src_toplevel == dest_toplevel) - { - /* Same toplevels */ - gdk_window_get_device_position_double (dest_toplevel, - device, - &x, &y, &state); - _gdk_synthesize_crossing_events (display, - src_window, - dest_window, - device, source_device, - crossing_mode, - x, y, state, - time, - NULL, - serial, FALSE); - } - else if (dest_toplevel == NULL) - { - gdk_window_get_device_position_double (src_toplevel, - device, - &x, &y, &state); - _gdk_synthesize_crossing_events (display, - src_window, - NULL, - device, source_device, - crossing_mode, - x, y, state, - time, - NULL, - serial, FALSE); - } - else - { - /* Different toplevels */ - gdk_window_get_device_position_double (src_toplevel, - device, - &x, &y, &state); - _gdk_synthesize_crossing_events (display, - src_window, - NULL, - device, source_device, - crossing_mode, - x, y, state, - time, - NULL, - serial, FALSE); - gdk_window_get_device_position_double (dest_toplevel, - device, - &x, &y, &state); - _gdk_synthesize_crossing_events (display, - NULL, - dest_window, - device, source_device, - crossing_mode, - x, y, state, - time, - NULL, - serial, FALSE); - } -} - static GdkWindow * get_current_toplevel (GdkDisplay *display, GdkDevice *device, @@ -932,7 +841,7 @@ switch_to_pointer_grab (GdkDisplay *display, guint32 time, gulong serial) { - GdkWindow *src_window, *pointer_window, *new_toplevel; + GdkWindow *pointer_window, *new_toplevel; GdkPointerWindowInfo *info; GList *old_grabs; GdkModifierType state; @@ -946,26 +855,8 @@ switch_to_pointer_grab (GdkDisplay *display, if (grab) { /* New grab is in effect */ - - /* We need to generate crossing events for the grab. - * However, there are never any crossing events for implicit grabs - * TODO: ... Actually, this could happen if the pointer window - * doesn't have button mask so a parent gets the event... - */ if (!grab->implicit) { - /* We send GRAB crossing events from the window under the pointer to the - grab window. Except if there is an old grab then we start from that */ - if (last_grab) - src_window = last_grab->window; - else - src_window = info->window_under_pointer; - - if (src_window != grab->window) - synthesize_crossing_events (display, device, source_device, - src_window, grab->window, - GDK_CROSSING_GRAB, time, serial); - /* !owner_event Grabbing a window that we're not inside, current status is now NULL (i.e. outside grabbed window) */ if (!grab->owner_events && info->window_under_pointer != grab->window) @@ -1029,12 +920,6 @@ switch_to_pointer_grab (GdkDisplay *display, NULL, NULL); } - if (!info->need_touch_press_enter && - pointer_window != last_grab->window) - synthesize_crossing_events (display, device, source_device, - last_grab->window, pointer_window, - GDK_CROSSING_UNGRAB, time, serial); - /* We're now ungrabbed, update the window_under_pointer */ _gdk_display_set_window_under_pointer (display, device, pointer_window); } diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index f9fab82487..14bea5aa3d 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -5466,37 +5466,6 @@ point_in_input_window (GdkWindow *window, return FALSE; } -static void -convert_toplevel_coords_to_window (GdkWindow *window, - gdouble toplevel_x, - gdouble toplevel_y, - gdouble *window_x, - gdouble *window_y) -{ - GdkWindow *parent; - gdouble x, y; - GList *children, *l; - - x = toplevel_x; - y = toplevel_y; - - children = NULL; - while ((parent = window->parent) != NULL && - (parent->window_type != GDK_WINDOW_ROOT)) - { - children = g_list_prepend (children, window); - window = parent; - } - - for (l = children; l != NULL; l = l->next) - gdk_window_coords_from_parent (l->data, x, y, &x, &y); - - g_list_free (children); - - *window_x = x; - *window_y = y; -} - GdkWindow * _gdk_window_find_child_at (GdkWindow *window, double x, @@ -5670,43 +5639,6 @@ gdk_window_get_support_multidevice (GdkWindow *window) /* send motion events if the right buttons are down */ -static GdkWindow * -find_common_ancestor (GdkWindow *win1, - GdkWindow *win2) -{ - GdkWindow *tmp; - GList *path1 = NULL, *path2 = NULL; - GList *list1, *list2; - - tmp = win1; - while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT) - { - path1 = g_list_prepend (path1, tmp); - tmp = tmp->parent; - } - - tmp = win2; - while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT) - { - path2 = g_list_prepend (path2, tmp); - tmp = tmp->parent; - } - - list1 = path1; - list2 = path2; - tmp = NULL; - while (list1 && list2 && (list1->data == list2->data)) - { - tmp = list1->data; - list1 = list1->next; - list2 = list2->next; - } - g_list_free (path1); - g_list_free (path2); - - return tmp; -} - GdkEvent * _gdk_make_event (GdkWindow *window, GdkEventType type, @@ -5827,288 +5759,6 @@ _gdk_make_event (GdkWindow *window, return event; } -static void -send_crossing_event (GdkDisplay *display, - GdkWindow *toplevel, - GdkWindow *window, - GdkEventType type, - GdkCrossingMode mode, - GdkNotifyType notify_type, - GdkWindow *subwindow, - GdkDevice *device, - GdkDevice *source_device, - gdouble toplevel_x, - gdouble toplevel_y, - GdkModifierType mask, - guint32 time_, - GdkEvent *event_in_queue, - gulong serial) -{ - GdkEvent *event; - guint32 window_event_mask, type_event_mask; - GdkDeviceGrabInfo *grab; - GdkTouchGrabInfo *touch_grab = NULL; - GdkPointerWindowInfo *pointer_info; - gboolean block_event = FALSE; - GdkEventSequence *sequence; - - grab = _gdk_display_has_device_grab (display, device, serial); - pointer_info = _gdk_display_get_pointer_info (display, device); - - sequence = gdk_event_get_event_sequence (event_in_queue); - if (sequence) - touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial); - - if (touch_grab) - { - if (window != touch_grab->window) - return; - - window_event_mask = touch_grab->event_mask; - } - else if (grab != NULL && - !grab->owner_events) - { - /* !owner_event => only report events wrt grab window, ignore rest */ - if ((GdkWindow *)window != grab->window) - return; - window_event_mask = grab->event_mask; - } - else - window_event_mask = window->event_mask; - - if (type == GDK_ENTER_NOTIFY && - (pointer_info->need_touch_press_enter || - (source_device && - gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)) && - mode != GDK_CROSSING_TOUCH_BEGIN && - mode != GDK_CROSSING_TOUCH_END) - { - pointer_info->need_touch_press_enter = TRUE; - block_event = TRUE; - } - else if (type == GDK_LEAVE_NOTIFY) - { - type_event_mask = GDK_LEAVE_NOTIFY_MASK; - window->devices_inside = g_list_remove (window->devices_inside, device); - - if (!window->support_multidevice && window->devices_inside) - { - /* Block leave events unless it's the last pointer */ - block_event = TRUE; - } - } - else - { - type_event_mask = GDK_ENTER_NOTIFY_MASK; - - if (!window->support_multidevice && window->devices_inside) - { - /* Only emit enter events for the first device */ - block_event = TRUE; - } - - if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER && - gdk_device_get_mode (device) != GDK_MODE_DISABLED && - !g_list_find (window->devices_inside, device)) - window->devices_inside = g_list_prepend (window->devices_inside, device); - } - - if (block_event) - return; - - if (window_event_mask & type_event_mask) - { - event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE); - gdk_event_set_device (event, device); - gdk_event_set_seat (event, gdk_device_get_seat (device)); - - if (source_device) - gdk_event_set_source_device (event, source_device); - - event->crossing.time = time_; - event->crossing.subwindow = subwindow; - if (subwindow) - g_object_ref (subwindow); - convert_toplevel_coords_to_window ((GdkWindow *)window, - toplevel_x, toplevel_y, - &event->crossing.x, &event->crossing.y); - event->crossing.x_root = toplevel_x + toplevel->x; - event->crossing.y_root = toplevel_y + toplevel->y; - event->crossing.mode = mode; - event->crossing.detail = notify_type; - event->crossing.focus = FALSE; - event->crossing.state = mask; - } -} - - -/* The coordinates are in the toplevel window that src/dest are in. - * src and dest are always (if != NULL) in the same toplevel, as - * we get a leave-notify and set the window_under_pointer to null - * before crossing to another toplevel. - */ -void -_gdk_synthesize_crossing_events (GdkDisplay *display, - GdkWindow *src, - GdkWindow *dest, - GdkDevice *device, - GdkDevice *source_device, - GdkCrossingMode mode, - double toplevel_x, - double toplevel_y, - GdkModifierType mask, - guint32 time_, - GdkEvent *event_in_queue, - gulong serial, - gboolean non_linear) -{ - GdkWindow *c; - GdkWindow *win, *last, *next; - GList *path, *list; - GdkWindow *a; - GdkWindow *b; - GdkWindow *toplevel; - GdkNotifyType notify_type; - - /* TODO: Don't send events to toplevel, as we get those from the windowing system */ - - a = (src && GDK_IS_WINDOW (src)) ? src : NULL; - b = (dest && GDK_IS_WINDOW (dest)) ? dest : NULL; - - if (src == dest) - return; /* No crossings generated between src and dest */ - - if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER) - { - if (a && gdk_window_get_device_events (src, device) == 0) - a = NULL; - - if (b && gdk_window_get_device_events (dest, device) == 0) - b = NULL; - } - - if (!a && !b) - return; - - c = find_common_ancestor (a, b); - - non_linear |= (c != a) && (c != b); - - if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */ - { - toplevel = gdk_window_get_toplevel (a); - - /* Traverse up from a to (excluding) c sending leave events */ - if (non_linear) - notify_type = GDK_NOTIFY_NONLINEAR; - else if (c == a) - notify_type = GDK_NOTIFY_INFERIOR; - else - notify_type = GDK_NOTIFY_ANCESTOR; - send_crossing_event (display, toplevel, - a, GDK_LEAVE_NOTIFY, - mode, - notify_type, - NULL, device, source_device, - toplevel_x, toplevel_y, - mask, time_, - event_in_queue, - serial); - - if (c != a) - { - if (non_linear) - notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL; - else - notify_type = GDK_NOTIFY_VIRTUAL; - - last = a; - win = a->parent; - while (win != c && win->window_type != GDK_WINDOW_ROOT) - { - send_crossing_event (display, toplevel, - win, GDK_LEAVE_NOTIFY, - mode, - notify_type, - (GdkWindow *)last, - device, source_device, - toplevel_x, toplevel_y, - mask, time_, - event_in_queue, - serial); - - last = win; - win = win->parent; - } - } - } - - if (b) /* Might not be a dest, e.g. if we're moving out of the window */ - { - toplevel = gdk_window_get_toplevel ((GdkWindow *)b); - - /* Traverse down from c to b */ - if (c != b) - { - path = NULL; - win = b->parent; - while (win != c && win->window_type != GDK_WINDOW_ROOT) - { - path = g_list_prepend (path, win); - win = win->parent; - } - - if (non_linear) - notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL; - else - notify_type = GDK_NOTIFY_VIRTUAL; - - list = path; - while (list) - { - win = list->data; - list = list->next; - if (list) - next = list->data; - else - next = b; - - send_crossing_event (display, toplevel, - win, GDK_ENTER_NOTIFY, - mode, - notify_type, - (GdkWindow *)next, - device, source_device, - toplevel_x, toplevel_y, - mask, time_, - event_in_queue, - serial); - } - g_list_free (path); - } - - - if (non_linear) - notify_type = GDK_NOTIFY_NONLINEAR; - else if (c == a) - notify_type = GDK_NOTIFY_ANCESTOR; - else - notify_type = GDK_NOTIFY_INFERIOR; - - send_crossing_event (display, toplevel, - b, GDK_ENTER_NOTIFY, - mode, - notify_type, - NULL, - device, source_device, - toplevel_x, toplevel_y, - mask, time_, - event_in_queue, - serial); - } -} - void _gdk_display_set_window_under_pointer (GdkDisplay *display, GdkDevice *device, -- 2.30.2